<?php

declare(strict_types=1);

namespace App\Controller\Admin\User;

use App\Entity\AdminUserGroup;
use App\Event\AdminUserGroupRemoveEvent;
use App\Utils\Annotation\ApiAuthority;
use App\Utils\Annotation\ApiName;
use App\Utils\Annotation\ApiParam;
use App\Utils\Traits\ControllerTrait;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

/**
 * Class AdminUserGroupController
 * @package App\Controller\Admin\User
 * @Route("/admin/user/admin-user-group", name="admin-user-admin_user_group-")
 * @ApiName(name="用户组")
 */
class AdminUserGroupController extends AbstractController {
    use ControllerTrait;

    /**
     * @ApiName(name="用户组列表")
     * @ApiParam(name="name", type="string", comment="用户组名称")
     * @ApiParam(name="created_at", type="string", comment="创建日期")
     * @ApiParam(name="page", type="integer", comment="页码数", default="1")
     * @ApiParam(name="limit", type="integer", comment="每页条数", default="10")
     * @ApiAuthority(need="admin.user.admin_user_group")
     * @Route("/list", methods={"GET"}, name="list")
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     * @throws \Exception
     */
    public function list (Request $request) {
        $params = $this->onlyDeclare($request);
        $admin_user_group_data = $this->getDoctrine()->getRepository(AdminUserGroup::class)->search($params);
        $admin_user_group_total = $this->getDoctrine()->getRepository(AdminUserGroup::class)->searchTotal($params);
        foreach ($admin_user_group_data as &$admin_user_group) {
            $admin_user_group['created_at'] = $admin_user_group['created_at']->format('Y-m-d H:i:s');
        }
        return json_success([
            'data'  => $admin_user_group_data,
            'total' => $admin_user_group_total,
        ]);
    }

    /**
     * @ApiName(name="获取指定用户组信息")
     * @ApiParam(name="id", type="integer", comment="用户ID", require=true)
     * @ApiAuthority(need="admin.user.admin_user_group")
     * @Route("/info", methods={"GET"}, name="info")
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     * @throws \Exception
     */
    public function info (Request $request) {
        $params = $this->onlyDeclare($request);
        $admin_user_group = $this->getDoctrine()->getRepository(AdminUserGroup::class)->getOneById($params['id']);
        if ($admin_user_group) {
            return json_success($admin_user_group[0]);
        } else {
            return json_failure('用户组不存在');
        }
    }

    /**
     * @ApiName(name="用户组添加")
     * @ApiParam(name="name", type="string", comment="用户组名", require=true)
     * @ApiParam(name="module_ids", type="array", comment="模块集合", require=true)
     * @ApiAuthority(need="admin.user.admin_user_group")
     * @Route("/create", methods={"POST"}, name="create")
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     * @throws \Exception
     */
    public function create (Request $request) {
        $params = $this->onlyDeclare($request);
        if (count($params['module_ids']) == 0) {
            return json_failure('授权模块不能为空');
        }
        $admin_user_group_name = $this->getDoctrine()->getRepository(AdminUserGroup::class)->findOneBy(['name' => $params['name']]);
        if ($admin_user_group_name) {
            return json_failure('用户组名称"'.$params['name'].'"已经存在');
        }
        $admin_user_group = new AdminUserGroup();
        $admin_user_group->setName($params['name']);
        $admin_user_group->setModuleIds(json_encode($params['module_ids']));
        $this->getDoctrine()->getManager()->persist($admin_user_group);
        $this->getDoctrine()->getManager()->flush();
        return json_success();
    }

    /**
     * @ApiName(name="用户组更新")
     * @ApiParam(name="id", type="integer", comment="用户组ID", require=true)
     * @ApiParam(name="name", type="string", comment="用户组名", require=true)
     * @ApiParam(name="module_ids", type="array", comment="模块集合", require=true)
     * @ApiAuthority(need="admin.user.admin_user_group")
     * @Route("/update", methods={"POST"}, name="update")
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     * @throws \Exception
     */
    public function update (Request $request) {
        $params = $this->onlyDeclare($request);
        $admin_user_group = $this->getDoctrine()->getRepository(AdminUserGroup::class)->find($params['id']);
        if (!$admin_user_group) {
            return json_failure('用户组不存在');
        }
        $admin_user_group_name = $this->getDoctrine()->getRepository(AdminUserGroup::class)->findOneByFieldAndNotId('name', $params['name'], $params['id']);
        if ($admin_user_group_name) {
            return json_failure('用户组名"'.$params['name'].'"已经存在');
        }
        try {
            $admin_user_group->setName($params['name']);
            $admin_user_group->setModuleIds(json_encode($params['module_ids']));
            $this->getDoctrine()->getManager()->persist($admin_user_group);
            $this->getDoctrine()->getManager()->flush();
            return json_success();
        } catch (\Exception $e) {
            return json_failure($e->getMessage());
        }
    }

    /**
     * @ApiName(name="用户组删除", description="用户组删除会检查是否有关联用户，且会同步更新用户组缓存")
     * @ApiParam(name="id", type="integer", comment="用户组ID", require=true)
     * @ApiAuthority(need="admin.user.admin_user_group")
     * @Route("/delete", methods={"POST"}, name="delete")
     * @param Request $request
     * @param EventDispatcherInterface $eventDispatcher
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     * @throws \Exception
     */
    public function delete (Request $request, EventDispatcherInterface $eventDispatcher) {
        $params = $this->onlyDeclare($request);
        $admin_user_group = $this->getDoctrine()->getRepository(AdminUserGroup::class)->find($params['id']);
        if (!$admin_user_group) {
            return json_failure('用户组不存在');
        }
        if ($admin_user_group->getIsSuper()) {
            return json_failure('超级管理员组不能手动删除，请联系系统管理员');
        }
        $has_admin_user = $this->getDoctrine()->getRepository(AdminUserGroup::class)->hasAdminUser($admin_user_group->getId());
        if ($has_admin_user) {
            return json_failure('当前用户组下有用户关联不能删除');
        }
        $this->getDoctrine()->getManager()->remove($admin_user_group);
        $this->getDoctrine()->getManager()->flush();

        $eventDispatcher->dispatch(new AdminUserGroupRemoveEvent($params['id']), AdminUserGroupRemoveEvent::NAME);

        return json_success();
    }
}